package cn.bytets.rpc.api.code;

/**
 * 对通信消息的消息头编解码工具类
 */
public class BytesUtils {
    /**消息头长度*/
    public static final int HEADER_LENGTH = 16;
    /**魔数,作用是安全校验*/
    public static final short MAGIC = (short) 0xdabb;
    public static final byte MAGIC_HIGH = short2bytes(MAGIC)[0];
    public static final byte MAGIC_LOW = short2bytes(MAGIC)[1];
    /**
     * 请求方式
     */
    public static final byte FLAG_REQUEST = (byte) 0x80;

    public static void main(String[] args) {
        byte a = (byte) 0x10|4;
        System.out.println(a&7);
    }
    /**
     * 数据长度解码
     *
     * @param b   byte array.
     * @param off offset.
     * @return int.
     */
    public static int bytesDataLen2int(byte[] b, int off) {
        off = getDefaultDataLenOff(off);
        return ((b[off + 3] & 0xFF) << 0) +
                ((b[off + 2] & 0xFF) << 8) +
                ((b[off + 1] & 0xFF) << 16) +
                ((b[off + 0]) << 24);
    }

    /**
     * 数据长度(byte的长度为 -128~127 = 255) 4位长度
     */
    public static void bytesDataLen(byte[] b,int v, int off){
        off = getDefaultDataLenOff(off);
        b[off + 3] = (byte) v;
        b[off + 2] = (byte) (v >>> 8);
        b[off + 1] = (byte) (v >>> 16);
        b[off + 0] = (byte) (v >>> 24);
    }

    /**
     * 消息头数据长度保存位置默认从 12-15
     * @param off
     * @return
     */
    public static int getDefaultDataLenOff(int off){
        if (off==-1){
            return 12;
        }
        return off;
    }
    /**
     * 消息头request id保存位置默认从 4-11
     * @param off
     * @return
     */
    public static int getDefaultDataRequestIdOff(int off){
        if (off==-1){
            return 4;
        }
        return off;
    }
    /**
     * 解码消息头 Request Id
     * 注: 这里为什么要 & 0xFFL(255),因为byte的数据区间为 -128-127 = 255
     * @param b   byte array.
     * @param off offset.
     * @return long.
     */
    public static long bytesRequestId2Long(byte[] b, int off) {
        off = getDefaultDataRequestIdOff(off);
        return ((b[off + 7] & 0xFFL) << 0) +
                ((b[off + 6] & 0xFFL) << 8) +
                ((b[off + 5] & 0xFFL) << 16) +
                ((b[off + 4] & 0xFFL) << 24) +
                ((b[off + 3] & 0xFFL) << 32) +
                ((b[off + 2] & 0xFFL) << 40) +
                ((b[off + 1] & 0xFFL) << 48) +
                (((long) b[off + 0]) << 56);
    }
    /**
     * 编码消息头Request Id 8位长度
     *
     * @param v   value.
     * @param b   byte array.
     * @param off array offset.
     */
    public static void bytesRequestId(long v, byte[] b, int off) {
        off = getDefaultDataRequestIdOff(off);
        b[off + 7] = (byte) v;
        b[off + 6] = (byte) (v >>> 8);
        b[off + 5] = (byte) (v >>> 16);
        b[off + 4] = (byte) (v >>> 24);
        b[off + 3] = (byte) (v >>> 32);
        b[off + 2] = (byte) (v >>> 40);
        b[off + 1] = (byte) (v >>> 48);
        b[off + 0] = (byte) (v >>> 56);
    }

    /**
     * to byte array.
     *
     * @param v value.
     * @return byte[].
     */
    public static byte[] short2bytes(short v) {
        byte[] ret = {0, 0};
        short2bytes(v, ret);
        return ret;
    }
    /**
     * to byte array.
     *
     * @param v value.
     * @param b byte array.
     */
    public static void short2bytes(short v, byte[] b) {
        short2bytes(v, b, 0);
    }
    /**
     * to byte array. 魔数高低位
     *
     * @param v value.
     * @param b byte array.
     */
    public static void short2bytes(short v, byte[] b, int off) {
        b[off + 1] = (byte) v;
        b[off + 0] = (byte) (v >>> 8);
    }

    public static void bytes(byte[] b,int off,int v){
        b[off] = (byte) v;
    }
    public static int getBytes(byte[] b,int off){
        return b[off];
    }
}
